/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @addtogroup USB
 * @{
 *
 * @brief Defines the standard APIs of the USB function.
 *
 * This module declares the custom data types and functions used to obtain descriptors, interface objects, and request objects, and to submit requests.
 *
 * @since 3.0
 * @version 1.0
 */

/**
 * @file usbd_client.h
 *
 * @brief Declares the standard USB driver APIs.
 *
 * @since 3.0
 * @version 1.0
 */

#ifndef USBD_CLIENT_H
#define USBD_CLIENT_H

#include "usb_param.h"
#include "usbd_subscriber.h"

namespace OHOS {
namespace USB {
/**
 * @brief USB driver client class.
 *
 * @since 3.0
 * @version 1.0
 */
class UsbdClient {
public:
    /**
     * @brief Obtains an instance of the USB driver class.
     *
     * @since 3.0
     * @version 1.0
     */
    static UsbdClient &GetInstance();

    /**
     * @brief Opens a USB device to set up a connection.
     *
     * @param dev USB device address. For details, see {@link UsbDev}.
     *
     * @return **0**: The operation is successful.
     * @return A non-0 value: The operation has failed.
     *
     * @since 3.0
     * @version 1.0
     */
    int32_t OpenDevice(const UsbDev &dev);

    /**
     * @brief Closes a USB device to release all system resources related to the device.
     *
     * @param dev USB device address. For details, see {@link UsbDev}.
     *
     * @return **0**: The operation is successful.
     * @return A non-0 value: The operation has failed.
     *
     * @since 3.0
     * @version 1.0
     */
    int32_t CloseDevice(const UsbDev &dev);

    /**
     * @brief Obtains the USB device descriptor.
     *
     * @param dev USB device address. For details, see {@link UsbDev}.
     * @param descriptor USB device descriptor.
     *
     * @return **0**: The operation is successful.
     * @return A non-0 value: The operation has failed.
     *
     * @since 3.0
     * @version 1.0
     */
    int32_t GetDeviceDescriptor(const UsbDev &dev, std::vector<uint8_t> &descriptor);

    /**
     * @brief Obtains the string descriptor of a USB device based on the specified string ID.
     *
     * @param dev USB device address. For details, see {@link UsbDev}.
     * @param descId USB string ID.
     * @param descriptor String descriptor used to obtain the USB device configuration.
     *
     * @return **0**: The operation is successful.
     * @return A non-0 value: The operation has failed.
     *
     * @since 3.0
     * @version 1.0
     */
    int32_t GetStringDescriptor(const UsbDev &dev, uint8_t descId, std::vector<uint8_t> &descriptor);

    /**
     * @brief Obtains the configuration descriptor of a USB device based on the specified configuration ID.
     *
     * @param dev USB device address. For details, see {@link UsbDev}.
     * @param descId USB configuration ID.
     * @param descriptor Configuration descriptor used to obtain the USB device configuration.
     *
     * @return **0**: The operation is successful.
     * @return A non-0 value: The operation has failed.
     *
     * @since 3.0
     * @version 1.0
     */
    int32_t GetConfigDescriptor(const UsbDev &dev, uint8_t descId, std::vector<uint8_t> &descriptor);

    /**
     * @brief Obtains the raw descriptor.
     *
     * @param dev USB device address. For details, see {@link UsbDev}.
     * @param descriptor Raw descriptor of the USB device.
     *
     * @return **0**: The operation is successful.
     * @return A non-0 value: The operation has failed.
     *
     * @since 3.0
     * @version 1.0
     */
    int32_t GetRawDescriptor(const UsbDev &dev, std::vector<uint8_t> &descriptor);
    
    /**
     * @brief Obtains the file descriptor.
     *
     * @param dev USB device address. For details, see {@link UsbDev}.
     * @param fd File descriptor of the USB device.
     *
     * @return **0**: The operation is successful.
     * @return A non-0 value: The operation has failed.
     *
     * @since 3.0
     * @version 1.0
     */
    int32_t GetFileDescriptor(const UsbDev &dev, int32_t &fd);

    /**
     * @brief Sets the USB device configuration.
     *
     * @param dev USB device address. For details, see {@link UsbDev}.
     * @param configIndex Index of the USB device configuration.
     *
     * @return **0**: The operation is successful.
     * @return A non-0 value: The operation has failed.
     *
     * @since 3.0
     * @version 1.0
     */
    int32_t SetConfig(const UsbDev &dev, uint8_t configIndex);

    /**
     * @brief Obtains the USB device configuration.
     *
     * @param dev USB device address. For details, see {@link UsbDev}.
     * @param configIndex Index of the USB device configuration.
     *
     * @return **0**: The operation is successful.
     * @return A non-0 value: The operation has failed.
     *
     * @since 3.0
     * @version 1.0
     */
    int32_t GetConfig(const UsbDev &dev, uint8_t &configIndex);

    /**
     * @brief Claims a USB interface exclusively. This must be done before data transfer.
     *
     * @param dev USB device address. For details, see {@link UsbDev}.
     * @param interfaceid USB interface ID.
     * @param force Whether to perform the operation forcibly. The value **1"" means to perform the operation forcibly, and the value **0** indicates the opposite.
     *
     * @return **0**: The operation is successful.
     * @return A non-0 value: The operation has failed.
     *
     * @since 3.0
     * @version 1.0
     */
    int32_t ClaimInterface(const UsbDev &dev, uint8_t interfaceid, uint8_t force);

    /**
     * @brief Releases a USB interface. This is usually done after data transfer.
     *
     * @param dev USB device address. For details, see {@link UsbDev}.
     * @param interfaceid USB interface ID.
     *
     * @return **0**: The operation is successful.
     * @return A non-0 value: The operation has failed.
     *
     * @since 3.0
     * @version 1.0
     */
    int32_t ReleaseInterface(const UsbDev &dev, uint8_t interfaceid);

    /**
     * @brief Sets the alternate settings for the specified USB interface. This allows you to switch between two interfaces with the same ID but different alternate settings.
     *
     * @param dev USB device address. For details, see {@link UsbDev}.
     * @param interfaceid USB interface ID.
     * @param altIndex Index of the alternate settings of the USB interface.
     *
     * @return **0**: The operation is successful.
     * @return A non-0 value: The operation has failed.
     * @since 3.0
     * @version 1.0
     */
    int32_t SetInterface(const UsbDev &dev, uint8_t interfaceid, uint8_t altIndex);

    /**
     * @brief Reads data on a specified endpoint during bulk transfer. The endpoint must be in the data reading direction. You can specify a timeout duration if needed.
     *
     * @param dev USB device address. For details, see {@link UsbDev}.
     * @param pipe USB device pipe. For details, see {@link UsbPipe}.
     * @param timeout Timeout interval.
     * @param data Data to be read.
     *
     * @return **0**: The operation is successful.
     * @return A non-0 value: The operation has failed.
     *
     * @since 3.0
     * @version 1.0
     */
    int32_t BulkTransferRead(const UsbDev &dev, const UsbPipe &pipe, int32_t timeout, std::vector<uint8_t> &data);

    /**
     * @brief Writes data on a specified endpoint during bulk transfer. The endpoint must be in the data writing direction.
     *
     * @param dev USB device address. For details, see {@link UsbDev}.
     * @param pipe USB device pipe. For details, see {@link UsbPipe}.
     * @param timeout Timeout interval.
     * @param data Data to be written.
     *
     * @return **0**: The operation is successful.
     * @return A non-0 value: The operation has failed.
     *
     * @since 3.0
     * @version 1.0
     */
    int32_t BulkTransferWrite(const UsbDev &dev, const UsbPipe &pipe, int32_t timeout,
        const std::vector<uint8_t> &data);

    /**
     * @brief Performs control transfer for endpoint 0 of the device. The data transfer direction is determined by the request type. If the result of <b>requestType</b>&
     * <b>USB_ENDPOINT_DIR_MASK</b> is <b>USB_DIR_OUT</b>, the endpoint is in the data writing direction; if the result is <b>USB_DIR_IN</b>, the endpoint is in the data reading direction.
     *
     * @param dev USB device address. For details, see {@link UsbDev}.
     * @param ctrl Control data packet structure. For details, see {@link UsbCtrlTransfer}.
     * @param data Data to be read or written.
     *
     * @return **0**: The operation is successful.
     * @return A non-0 value: The operation has failed.
     *
     * @since 3.0
     * @version 1.0
     */
    int32_t ControlTransfer(const UsbDev &dev, const UsbCtrlTransfer &ctrl, std::vector<uint8_t> &data);

    /**
     * @brief Reads data on a specified endpoint during interrupt transfer. The endpoint must be in the data reading direction.
     *
     * @param dev USB device address. For details, see {@link UsbDev}.
     * @param pipe USB device pipe. For details, see {@link UsbPipe}.
     * @param timeout Timeout interval.
     * @param data Data to be read.
     *
     * @return **0**: The operation is successful.
     * @return A non-0 value: The operation has failed.
     *
     * @since 3.0
     * @version 1.0
     */
    int32_t InterruptTransferRead(const UsbDev &dev, const UsbPipe &pipe, int32_t timeout, std::vector<uint8_t> &data);

    /**
     * @brief Writes data on a specified endpoint during interrupt transfer. The endpoint must be in the data writing direction.
     *
     * @param dev USB device address. For details, see {@link UsbDev}.
     * @param pipe USB device pipe. For details, see {@link UsbPipe}.
     * @param timeout Timeout interval.
     * @param data Data to be written.
     *
     * @return **0**: The operation is successful.
     * @return A non-0 value: The operation has failed.
     *
     * @since 3.0
     * @version 1.0
     */
    int32_t InterruptTransferWrite(const UsbDev &dev, const UsbPipe &pipe, int32_t timeout, std::vector<uint8_t> &data);

    /**
     * @brief Reads data on a specified endpoint during isochronous transfer. The endpoint must be in the data reading direction.
     *
     * @param dev USB device address. For details, see {@link UsbDev}.
     * @param pipe USB device pipe. For details, see {@link UsbPipe}.
     * @param timeout Timeout interval.
     * @param data Data to be read.
     *
     * @return **0**: The operation is successful.
     * @return A non-0 value: The operation has failed.
     *
     * @since 3.0
     * @version 1.0
     */
    int32_t IsoTransferRead(const UsbDev &dev, const UsbPipe &pipe, int32_t timeout, std::vector<uint8_t> &data);

    /**
     * @brief Writes data on a specified endpoint during isochronous transfer. The endpoint must be in the data writing direction.
     *
     * @param dev USB device address. For details, see {@link UsbDev}.
     * @param pipe USB device pipe. For details, see {@link UsbPipe}.
     * @param timeout Timeout interval.
     * @param data Data to be read.
     *
     * @return **0**: The operation is successful.
     * @return A non-0 value: The operation has failed.
     *
     * @since 3.0
     * @version 1.0
     */
    int32_t IsoTransferWrite(const UsbDev &dev, const UsbPipe &pipe, int32_t timeout, std::vector<uint8_t> &data);

    /**
     * @brief Sends or receives requests for isochronous transfer on a specified endpoint. The data transfer direction is determined by the endpoint direction.
     *
     * @param dev USB device address. For details, see {@link UsbDev}.
     * @param pipe USB device pipe. For details, see {@link UsbPipe}.
     * @param clientData Client data.
     * @param buffer Buffer for data transfer.
     *
     * @return **0**: The operation is successful.
     * @return A non-0 value: The operation has failed.
     *
     * @since 3.0
     * @version 1.0
     */
    int32_t RequestQueue(const UsbDev &dev, const UsbPipe &pipe, const std::vector<uint8_t> &clientData,
        const std::vector<uint8_t> &buffer);

    /**
     * @brief Waits for the operation result of the isochronous transfer request in <b>RequestQueue</b>.
     *
     * @param dev USB device address. For details, see {@link UsbDev}.
     * @param clientData Client data.
     * @param buffer Buffer for data transfer.
     * @param timeout Timeout interval.
     *
     * @return **0**: The operation is successful.
     * @return A non-0 value: The operation has failed.
     *
     * @since 3.0
     * @version 1.0
     */
    int32_t RequestWait(const UsbDev &dev, std::vector<uint8_t> &clientData, std::vector<uint8_t> &buffer,
        int32_t timeout);

    /**
     * @brief Cancels the data transfer requests to be processed.
     *
     * @param dev USB device address. For details, see {@link UsbDev}.
     * @param pipe USB device pipe. For details, see {@link UsbPipe}.
     *
     * @return **0**: The operation is successful.
     * @return A non-0 value: The operation has failed.
     *
     * @since 3.0
     * @version 1.0
     */
    int32_t RequestCancel(const UsbDev &dev, const UsbPipe &pipe);

    /**
     * @brief Obtains the list of functions (represented by bit field) supported by the current USB device.
     *
     * @param funcs List of functions supported by the current USB device.
     *
     * @return **0**: The operation is successful.
     * @return A non-0 value: The operation has failed.
     *
     * @since 3.0
     * @version 1.0
     */
    int32_t GetCurrentFunctions(int32_t &funcs);

    /**
     * @brief Sets the list of functions (represented by bit field) supported by the current USB device.
     *
     * @param funcs List of functions supported by the current USB device.
     *
     * @return **0**: The operation is successful.
     * @return A non-0 value: The operation has failed.
     *
     * @since 3.0
     * @version 1.0
     */
    int32_t SetCurrentFunctions(int32_t funcs);

    /**
     * @brief Sets the role of a port.
     *
     * @param portId Port ID.
     * @param powerRole Power role.
     * @param dataRole Data role.
     *
     * @return **0**: The operation is successful.
     * @return A non-0 value: The operation has failed.
     *
     * @since 3.0
     * @version 1.0
     */
    int32_t SetPortRole(int32_t portId, int32_t powerRole, int32_t dataRole);

    /**
     * @brief Queries the current settings of a port.
     *
     * @param portId Port ID.
     * @param powerRole Power role.
     * @param dataRole Data role.
     * @param mode Port mode.
     *
     * @return **0**: The operation is successful.
     * @return A non-0 value: The operation has failed.
     *
     * @since 3.0
     * @version 1.0
     */
    int32_t QueryPort(int32_t &portId, int32_t &powerRole, int32_t &dataRole, int32_t &mode);

    /**
     * @brief Binds a subscriber.
     *
     * @param subscriber Subscriber to bind. For details, see {@link UsbdSubscriber}.
     *
     * @return **0**: The operation is successful.
     * @return A non-0 value: The operation has failed.
     *
     * @since 3.0
     * @version 1.0
     */
    int32_t BindUsbdSubscriber(const sptr<UsbdSubscriber> &subscriber);

    /**
     * @brief Unbinds a subscriber.
     *
     * @param subscriber Subscriber to unbind. For details, see {@link UsbdSubscriber}.
     *
     * @return **0**: The operation is successful.
     * @return A non-0 value: The operation has failed.
     *
     * @since 3.0
     * @version 1.0
     */
    int32_t UnbindUsbdSubscriber(const sptr<UsbdSubscriber> &subscriber);

    /**
     * @brief Registers a callback for isochronous bulk transfer.
     *
     * @param dev USB device address. For details, see {@link UsbDev}.
     * @param pipe USB device pipe. For details, see {@link UsbPipe}.
     * @param cb Reference to the callback.
     *
     * @return **0**: The operation is successful.
     * @return A non-0 value: The operation has failed.
     *
     * @since 3.0
     * @version 1.0
     */
    int32_t RegBulkCallback(const UsbDev &dev, const UsbPipe &pipe, const sptr<IRemoteObject> &cb);

    /**
     * @brief Unregisters the callback for isochronous bulk transfer.
     *
     * @param dev USB device address. For details, see {@link UsbDev}.
     * @param pipe USB device pipe. For details, see {@link UsbPipe}.
     *
     * @return **0**: The operation is successful.
     * @return A non-0 value: The operation has failed.
     *
     * @since 3.0
     * @version 1.0
     */
    int32_t UnRegBulkCallback(const UsbDev &dev, const UsbPipe &pipe);

    /**
     * @brief Reads data during isochronous bulk transfer.
     *
     * @param dev USB device address. For details, see {@link UsbDev}.
     * @param pipe USB device pipe. For details, see {@link UsbPipe}.
     * @param ashmem Shared memory, which is used to store the read data. For details, see {@link Ashmem}.
     *
     * @return **0**: The operation is successful.
     * @return A non-0 value: The operation has failed.
     *
     * @since 3.0
     * @version 1.0
     */
    int32_t BulkRead(const UsbDev &dev, const UsbPipe &pipe, sptr<Ashmem> &ashmem);

    /**
     * @brief Writes data during isochronous bulk transfer.
     *
     * @param dev USB device address. For details, see {@link UsbDev}.
     * @param pipe USB device pipe. For details, see {@link UsbPipe}.
     * @param ashmem Shared memory, which is used to store the written data. For details, see {@link Ashmem}.
     *
     * @return **0**: The operation is successful.
     * @return A non-0 value: The operation has failed.
     *
     * @since 3.0
     * @version 1.0
     */
    int32_t BulkWrite(const UsbDev &dev, const UsbPipe &pipe, sptr<Ashmem> &ashmem);

    /**
     * @brief Cancels the isochronous bulk transfer. The read and write operations on the current USB interface will be cancelled.
     *
     * @param dev USB device address. For details, see {@link UsbDev}.
     * @param pipe USB device pipe. For details, see {@link UsbPipe}.
     *
     * @return **0**: The operation is successful.
     * @return A non-0 value: The operation has failed.
     *
     * @since 3.0
     * @version 1.0
     */
    int32_t BulkCancel(const UsbDev &dev, const UsbPipe &pipe);
};
} /** namespace USB */
} /** namespace OHOS */
#endif // USBD_CLIENT_H
